package com.ljkj.cordial.chat.dao;

import com.ljkj.cordial.chat.base.ChatApp;

import org.greenrobot.greendao.AbstractDao;
import org.greenrobot.greendao.Property;
import org.greenrobot.greendao.async.AsyncOperation;
import org.greenrobot.greendao.async.AsyncOperationListener;
import org.greenrobot.greendao.async.AsyncSession;
import org.greenrobot.greendao.query.Query;
import org.greenrobot.greendao.query.QueryBuilder;
import org.greenrobot.greendao.query.WhereCondition;

import java.util.List;


/**
 * db控制类
 */
public class DbController {
    private final static String DB_NAME = "ljkj_cordial_database.db";

    private static DbController dbController;

    public static DbController getInstance() {
        if (dbController == null) {
            synchronized (DbController.class) {
                dbController = new DbController();
            }
        }
        return dbController;
    }


    private DaoMaster.DevOpenHelper helper;
    private DaoMaster readMaster;
    private DaoSession readSession;
    private DaoMaster writeMaster;
    private DaoSession writeSession;

    private void getHelper() {
        if (helper == null) {
            helper = new DbOpenHelper(ChatApp.getInstance().getApplicationContext(), DB_NAME);
        }
    }

    public DaoSession getWrite() {
        if (writeMaster == null) {
            getHelper();
            writeMaster = new DaoMaster(helper.getEncryptedWritableDb("lj123456"));
        }
        if (writeMaster.getDatabase().isDbLockedByCurrentThread()) {
            writeMaster.getDatabase().endTransaction();
        }
        if (writeSession == null) {
            writeSession = writeMaster.newSession();
        }else{
            writeSession.clear();
        }
        return writeSession;
    }


    public DaoSession getRead() {
        if (readMaster == null) {
            getHelper();
            readMaster = new DaoMaster(helper.getEncryptedReadableDb("lj123456"));
        }
        if (readMaster.getDatabase().isDbLockedByCurrentThread()) {
            readMaster.getDatabase().endTransaction();
        }
        if (readSession == null) {
            readSession = readMaster.newSession();
        }else{
            readSession.clear();
        }
        return readSession;
    }


    public void clear() {
        try {
            if (readSession != null) {
                readSession.clear();
//                readSession = null;
            }
            if (writeSession != null) {
                writeSession.clear();
//                writeSession = null;
            }
            if (readMaster != null) {
                if (readMaster.getDatabase().isDbLockedByCurrentThread()) {
                    readMaster.getDatabase().endTransaction();
                }
//                readMaster.getDatabase().close();
//                readMaster = null;
            }
            if (writeMaster != null) {
                if (writeMaster.getDatabase().isDbLockedByCurrentThread()) {
                    writeMaster.getDatabase().endTransaction();
                }
//                writeMaster.getDatabase().close();
//                writeMaster = null;
            }
//            if (helper != null) {
//                helper.close();
//                helper = null;
//            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 分页条件查询实体集合
     *
     * @param entityClass
     * @param offset
     * @param limit
     * @param where
     * @param selectionArgs
     * @param <T>
     * @return
     */
    public <T> List<T> queryPage(DaoSession daoSession, Class<T> entityClass, int offset, int limit, String where,
                                 Property properties, Object... selectionArgs) {
        AbstractDao<T, ?> dao = (AbstractDao<T, ?>) daoSession.getDao(entityClass);
        QueryBuilder<T> builder = dao.queryBuilder()
                .orderDesc(properties)
                .where(
                        new WhereCondition.StringCondition(where, selectionArgs))
                .offset(offset * limit)
                .limit(limit);
        return builder.list();
    }

    public <T> void query(Class cls, WhereCondition whereCondition, AsyncOperationListener operationListener) {
        AsyncSession asyncSession = getRead().startAsyncSession();
        asyncSession.setListenerMainThread(new AsyncOperationListener() {
            @Override
            public void onAsyncOperationCompleted(AsyncOperation operation) {
                if (operationListener != null) {
                    operationListener.onAsyncOperationCompleted(operation);
                }
            }
        });
        Query query = getRead().queryBuilder(cls).where(whereCondition).build();
        asyncSession.queryUnique(query);
    }

}
